package top.dreamcenter.rss.rsssolverweb.util;

import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.WebDriver;
import top.dreamcenter.rss.common.entity.RSS;
import top.dreamcenter.rss.common.util.RssHelper;
import top.dreamcenter.rss.rsssolverprotocal.SpiderTemplate;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Set;

/**
 * 单个爬虫助手，一个助手只处理一类rss需求，该类rss需求排版格式一样。
 *
 * 具体的，比如对于一个网站bilibili，获取用户的动态列表算是一类需求，获取用户的视频列表算是另外一类需求，须要两个助手分别跑数据，避免干扰。
 * 对于同一个需求，可以加入多个不同的频道，这些频道会在同一个助手中处理，比如查看b站用户的动态列表，不同用户的动态都可以在同一个helper中爬取。
 */
@Slf4j
public class SpiderHelper implements Runnable{

    private final WebDriver driver;
    private final SpiderTemplate spiderTemplate;
    private final String rootPath;
    private final String route;
    private final String cron;

    private Date lastRunAt;
    private String lastRunResult;

    private final Hashtable<String, RSS> storage = new Hashtable<>();
    private final Hashtable<String, String> config = new Hashtable<>();
    private final Hashtable<String, String> keyTable = new Hashtable<>();


    public SpiderHelper(WebDriver driver, SpiderTemplate spiderTemplate, String rootPath) {
        this.driver = driver;
        this.spiderTemplate = spiderTemplate;
        this.rootPath = rootPath;
        this.route = spiderTemplate.getRoute();
        this.cron = spiderTemplate.getCron();
    }

    @Override
    public void run() {
        try {

            log.warn(spiderTemplate.getRoute() + " started.");
            // 分配driver
            spiderTemplate.setDriver(driver);
            // 分配config
            spiderTemplate.setConfig(config);
            // 初始化cookies
            spiderTemplate.initCookies();
            // 配置路由
            File home = Paths.get(rootPath, route).toFile();
            if (!home.exists()) home.mkdirs();
            // 调用
            storage.forEach((k ,v) -> {
                // 执行调取器
                spiderTemplate.caller(k, v);
                String path = Paths.get(rootPath ,route, k + ".xml").toString();
                RssHelper rssHelper = new RssHelper(v);
                try {
                    rssHelper.saveToFile(path);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            // 设置最后一次成功执行的时间
            lastRunAt = Calendar.getInstance().getTime();
            lastRunResult = "成功";
        } catch (RuntimeException e) {
            lastRunAt = Calendar.getInstance().getTime();
            lastRunResult = "FAIL: " + e;
        }

    }


////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 列出所有的key
     * @return
     */
    public Hashtable<String, String> listKey() {
        return keyTable;
    }

    /**
     * 添加一个key
     * @param key
     */
    public void addKey(String key, String value) {
        keyTable.put(key, value);
        storage.put(key, new RSS());
    }

    /**
     * 删除一个key
     * @param key
     */
    public void delKey(String key) {
        keyTable.remove(key);
        storage.remove(key);
    }


////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 列出所有配置项
     * @return
     */
    public Hashtable<String, String> listConfig() {
        return config;
    }

    /**
     * 添加额外配置键值对
     * @param k
     * @param v
     */
    public void addConfig(String k, String v) {
        config.put(k, v);
    }

    /**
     * 删除一个配置项
     * @param k
     */
    public void delConfig(String k) {
        config.remove(k);
    }


////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 获取路由
     * @return
     */
    public String getRoute() {
        return route;
    }

    /**
     * 获取cron
     * @return
     */
    public String getCron() {
        return cron;
    }

////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 获取最后执行时间
     * @return
     */
    public Date getLastRunAt() {
        return lastRunAt;
    }

    /**
     * 获取最后执行结果
     * @return
     */
    public String getLastRunResult() {
        return lastRunResult;
    }
}
